﻿using System;
using System.Collections.Generic;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.datatype;
using umbraco.cms.businesslogic.member;
using umbraco.DataLayer;
using umbraco.interfaces;

namespace ProlificNotion.Umbraco.DataTypes
{
    public class FilteredMemberPickerPreValueEditor : CheckBoxList, IDataPrevalue
    {
        private BaseDataType dataType;

        /// <summary>
        /// Initializes a new instance of the <see cref="FilteredMemberPickerPreValueEditor"/> class.
        /// </summary>
        /// <param name="DataType">Type of the data.</param>
        public FilteredMemberPickerPreValueEditor(BaseDataType DataType)
        {
            this.dataType = DataType;
        }

        /// <summary>
        /// Gets the editor.
        /// </summary>
        /// <value>The editor.</value>
        public Control Editor
        {
            get { return this; }
        }

        /// <summary>
        /// Saves this instance.
        /// </summary>
        public void Save()
        {
            this.dataType.DBType = (DBTypes)Enum.Parse(typeof(DBTypes), DBTypes.Nvarchar.ToString(), true);
            Application.SqlHelper.ExecuteNonQuery("delete from cmsDataTypePreValues where datatypenodeid = @dtdefid", new IParameter[] { Application.SqlHelper.CreateParameter("@dtdefid", this.dataType.DataTypeDefinitionId) });
            Application.SqlHelper.ExecuteNonQuery("insert into cmsDataTypePreValues (datatypenodeid,[value],sortorder,alias) values (@dtdefid,@value,0,'')", new IParameter[] { Application.SqlHelper.CreateParameter("@dtdefid", this.dataType.DataTypeDefinitionId), Application.SqlHelper.CreateParameter("@value", GetSelectedFilters()) });
        }

        /// <summary>
        /// Binds a data source to the invoked server control and all its child controls.
        /// </summary>
        public override void DataBind()
        {
            // Loop through the membership roles and add them to the checkbox list
            foreach (string role in Roles.GetAllRoles())
            {
                ListItem li = new ListItem(role);
                this.Items.Add(new ListItem(role, MemberGroup.GetByName(role).Id.ToString()));
            }
            base.DataBind();
        }

        /// <summary>
        /// Calls the <see cref="M:System.Web.UI.WebControls.BaseDataBoundControl.DataBind"/> method if the <see cref="P:System.Web.UI.WebControls.BaseDataBoundControl.DataSourceID"/> property is set and the data-bound control is marked to require binding.
        /// </summary>
        protected override void EnsureDataBound()
        {
            try
            {
                if (this.RequiresDataBinding)
                {
                    this.DataBind();
                }
            }
            catch 
            {
                // Fail silently displaying no option to select role            
            }
        }

        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.WebControls.BaseDataBoundControl.DataBound"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnDataBound(EventArgs e)
        {
            SetSelectedFilters();
            base.OnDataBound(e);
        }

        /// <summary>
        /// Displays the <see cref="T:System.Web.UI.WebControls.CheckBoxList"/> on the client.
        /// </summary>
        /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that contains the output stream for rendering on the client.</param>
        protected override void Render(HtmlTextWriter writer)
        {
            writer.WriteLine("<div class=\"propertyItem\">");
            writer.WriteLine("<div class=\"propertyItemheader\">Select your filter(s)</div>");
            writer.WriteLine("<div class=\"propertyItemContent\">");
            base.Render(writer);
            writer.WriteLine("</div>");
            writer.WriteLine("</div>");
        }

        /// <summary>
        /// Gets the selected member group filters.
        /// </summary>
        /// <returns>A comma delimeted string containing the selected member group filters</returns>
        private string GetSelectedFilters()
        {
            List<String> filters = new List<string>();

            for (int i = 0; i < this.Items.Count; i++)
            {
                if (this.Items[i].Selected)
                {
                    filters.Add(this.Items[i].Value);
                }
            }

            return String.Join(",", filters.ToArray());
        }

        /// <summary>
        /// Sets the selected filters.
        /// </summary>
        /// <param name="filters">The filters.</param>
        private void SetSelectedFilters()
        {
            string[] f = Filters;
            
            if (f != null)
            {
                for (int i = 0; i <= f.GetUpperBound(0); i++)
                {
                    ListItem item = this.Items.FindByValue(f[i].ToString());
                    if (item != null)
                    {
                        item.Selected = true;
                    }
                }
            }
        }

        /// <summary>
        /// Gets the filters.
        /// </summary>
        /// <value>The filters.</value>
        public string[] Filters
        {
            get 
            {
                string filters = (string)Application.SqlHelper.ExecuteScalar<object>("select value from cmsDataTypePreValues where datatypenodeid = @datatypenodeid", new IParameter[] { Application.SqlHelper.CreateParameter("@datatypenodeid", this.dataType.DataTypeDefinitionId) });
                return filters.Split(',');
            }
        }
    }
}
